#ifndef spi_H
#define spi_H
#ifdef __cplusplus
extern "C"
{
#endif

    /*
        Chinese is encoded in Unicode. If it is garbled, please change the encoding method of the editor.
        SPI库 By启凡科创 适用于STC8平台MCU

        目前适配工作于：主机模式，高位优先，以字节为单位

        version:v2.0.2  2023-2-16
    */

#include "LIB_CONFIG.h" //包含启凡科创配置文件，如不是在此环境下自行注释并包含必要的变量类型定义等头文件

#ifndef SPI_EN
#define SPI_EN 0 // 如果配置文件未定义，则用户自定义，0禁用模块不不编译，1启用模块
#endif

#if SPI_EN

// 取消注释启用相应平台功能，不启用则无法使用，不使用的注释以节省资源, 都不使用全部注释以节省资源
// #define STC8H_TYPE
#define STC8A_TYPE
    // #define STC8A_DMA_TYPE

#define USE_SOFTWARE_SPI 1 // 0 硬件SPI  1模拟SPI

#if !USE_SOFTWARE_SPI // 硬件SPI配置
    typedef enum
    {
        spi_gpio_1, // 输出GPIO组为1
        spi_gpio_2, // 输出GPIO组为2
        spi_gpio_3, // 输出GPIO组为3
        spi_gpio_4, // 输出GPIO组为4
    } SPI_GPIO_NUM;

#ifdef STC8A_DMA_TYPE
    typedef enum
    {
        spi_clk_sys_clk_d4,  // 系统时钟/4
        spi_clk_sys_clk_d8,  // 系统时钟/8
        spi_clk_sys_clk_d16, // 系统时钟/16
        spi_clk_sys_clk_d2,  // 系统时钟/2
    } spi_clk;               // 看门狗时钟分频系数
#endif

#if (defined STC8A_TYPE | defined STC8H_TYPE)
    typedef enum
    {
        spi_clk_sys_clk_d4,  // 系统时钟/4
        spi_clk_sys_clk_d8,  // 系统时钟/8
        spi_clk_sys_clk_d16, // 系统时钟/16
        spi_clk_sys_clk_d32, // 系统时钟/32
    } spi_clk;               // 看门狗时钟分频系数
#endif
#else // 模拟SPI配置

#define SPI_SCLK_IO P55 // 时钟，如P1.3为P13
#define SPI_MOSI_IO P17 // 主出从入
#define SPI_MISO_IO -1  // 主入从出
#define SPI_CS_IO P54   // 片选

#endif

    // 初始化SPI相应IO口为推挽输出，不使用的IO参数给-1
    void spi_init_gpio(int8_t sclk, int8_t mosi, int8_t miso, int8_t cs);

#if !USE_SOFTWARE_SPI
    /*
        初始化SPI总线
        clk:SPI时钟分频系数：
            spi_clk_sys_clk_d2,   //系统时钟/2
            spi_clk_sys_clk_d4,   //系统时钟/4
            spi_clk_sys_clk_d8,   //系统时钟/8
            spi_clk_sys_clk_d16,  //系统时钟/16
        _io：硬件SPI映射GPIO组号，具体查看数据手册引脚图
    */
    void spi_begin(spi_clk clk, SPI_GPIO_NUM _io);

    /*
        设置SPI时钟分频
        clk:SPI时钟分频系数：
            spi_clk_sys_clk_d2,   //系统时钟/2
            spi_clk_sys_clk_d4,   //系统时钟/4
            spi_clk_sys_clk_d8,   //系统时钟/8
            spi_clk_sys_clk_d16,  //系统时钟/16
    */
    void spi_set_clk(spi_clk clk);
#else
    /**
     * @brief 开始通信,默认cs拉低
     */
    void spi_begin_trans_default();

    /**
     * @brief 结束通信，默认cs拉高
     *
     */
    void spi_end_trans_default();

    /**
     * @brief 开始通信,cs拉低
     *
     * @param cs 引脚号 如P1.3为13
     */
    void spi_begin_trans(uint8_t cs);

    /**
     * @brief 结束通信，cs拉高
     *
     * @param cs 引脚号 如P1.3为13
     */
    void spi_end_trans(uint8_t cs);

    // /**
    //  * @brief 写指定长度位
    //  *
    //  * @param dat 数据
    //  * @param len 位数
    //  */
    // void spi_write_bits(uint8_t *dat, uint8_t len);
#endif

    // 发送一个字节
    void spi_write(uint8_t dat);

    // 向指定从机发送两个字节value
    void spi_write16(uint16_t value);

    // 向指定从机连续发送dat指向的内容，长度len字节
    void spi_write_bytes(uint8_t *dat, uint8_t len);

#endif
#ifdef __cplusplus
}
#endif
#endif
